﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;

[RequireComponent(typeof(UIPanel))]
public class Window : MonoBehaviour {

	public class ChildAnchorInfo
	{
		public UIAnchor anchor;
		public Transform offset;
		public Vector3 defaultPos = Vector3.zero;
		public float deletaDepth = 0;
	}
	
	UIAnchor anchor;														//窗口锚点对象
	public Transform offset;												//窗口坐标对象
	public bool firstWindow = true;											//窗口是否为 一级窗口, 是否支持ESC 关闭
	public bool fullScreenWindow = false;									//窗口是否为全屏窗口
	
	public bool canShowWhenFullWindow = false;								//全屏时是否允许显示
	
	[SerializeField] List<Transform> hideChildren = new List<Transform>();	//窗口子对象, 隐藏对象列表
	List<ChildAnchorInfo> childAnchorInfoList = new List<ChildAnchorInfo>();//子锚点链表
	
	public bool firstOpen = false;											//是否是第一次打开窗口
	private int openCount = 0;
	private bool isInited = false; 
	
	[HideInInspector] public bool isUnload = true;
	
	//窗口当期位置及大小
	
	public Rect rect
	{
		get
		{
			Vector3 size = UIManager.GetControlSize(gameObject);
			Vector3 center = UIManager.GetControlCenterScreenPosition(gameObject);
			return new Rect(center.x - size.x / 2, center.y - size.y, size.x, size.y);
		}
	}
	
	protected Vector3 defaultOpenPos = Vector3.zero;		//窗口打开时默认的位置
	public bool resetPosAtOpened = true;					//窗口打开时是否重置位置
	
	//窗口是否显示
	public bool Visible
	{
		get
		{
			if(offset != null)
				return offset.gameObject.activeInHierarchy;
			else
				return gameObject.activeInHierarchy;
		}
		set
		{
			
		}
	}
	
	/// <summary>
	/// 本窗口基本信息初始化, 请不要调用其他窗口或逻辑数据, 重写该方法请先调用 base.Awake()
	/// </summary>
	protected virtual void Awake()
	{
		//全屏窗口设置为第一级窗口, 并且不能同时存在全屏窗口
		if(fullScreenWindow)
		{
			canShowWhenFullWindow = false;
			resetPosAtOpened = true;
		}
		
		anchor = transform.FindChild("Anchor").GetComponent<UIAnchor>();
		if(anchor == null)
		{
			Debug.LogError("窗口缺少锚点 UIAnchor:" + name + " ！ ");
			return;
		}
		offset = anchor.transform.FindChild("Offset");
		if(offset == null)
		{
			Debug.LogError("窗口缺少移动节点 Offset :" + name + " ！ ");
			return;
		}
		
		defaultOpenPos = offset.localPosition;
		
		List<UIAnchor> childAnchorList = NGUITools.FindInChildren<UIAnchor>(gameObject);
		foreach(UIAnchor childAnchor in childAnchorList)
		{
			if(childAnchor == anchor || !childAnchor.enabled)
				continue;
			else if(!NGUITools.IsChild(offset, childAnchor.transform))
			{
				Debug.LogError("子锚点不在Offset 下面： " + NGUITools.GetRelativeFullPath(transform, childAnchor.transform), childAnchor);
				continue;
			}
			
			ChildAnchorInfo childAnchorInfo = new ChildAnchorInfo();
			childAnchorInfo.anchor = childAnchor;
			Transform childAnchorOffset = childAnchor.transform.FindChild("Offset");
			if(childAnchorOffset == null)
			{
				Debug.LogError("锚点控件缺少移动节点 Offset: " + childAnchor.gameObject.name + " ！ ");
				continue;
			}
			else
			{
				childAnchorInfo.offset = childAnchorOffset;
				childAnchorInfo.defaultPos = childAnchorOffset.localPosition;
				childAnchorInfo.deletaDepth = childAnchorInfo.defaultPos.z - defaultOpenPos.z;
			}
			childAnchorInfoList.Add(childAnchorInfo);
		}
	}
	
	/// <summary>
	/// 窗口控件, 数据初始化, 可调用其他窗口或者逻辑
	/// </summary>
	public virtual void Init()
	{
		HideDefaultHideChildren();
		LoadAttributes();
	}
	
	public virtual void OnUpdate()
	{
		
	}
	
	/// <summary>
	/// 打开窗口, 重写该方法请先调用 base.Open(byuser)
	/// </param>
	public virtual void Open(bool byuser)
	{
	
		if(Visible)
			return;
		
		if(fullScreenWindow)
		{
//			UIManager.HideCurrentFullScreenWindow();
		}
		
		//如果有其他全屏窗口打开, 则不打开当前窗口
		if(!canShowWhenFullWindow)
		{
			foreach(Window window in UIManager.windows.Values)
			{
				if(window != this && window.Visible && window.fullScreenWindow)
					return;
			}
		}
		
		//检测已经打开的其他窗口
		if(fullScreenWindow)
		{
			UIManager.openedWindowListWhenOpen.Clear();
			foreach(Window window in UIManager.windows.Values)
			{
				if(window.Visible)
				{
					//已经打开的窗口都添加到列表中
					UIManager.openedWindowListWhenOpen.Add(window);
					
					//已经打开的可以再全屏模式下显示的窗口不关闭
					if(!window.canShowWhenFullWindow)
					{
						window.Close(true);
					}
				}
			}
		}
		
		//重置位置
		if(resetPosAtOpened)
		{
			if(firstWindow)
				offset.localPosition = defaultOpenPos;
			else
				offset.localPosition = new Vector3(defaultOpenPos.x, defaultOpenPos.y, 0);
		}
		
		SetVisible(true);
		
		//加载资源
		if(isUnload)
		{
			isUnload = false;
			UIManager.LoadWindowAssets(this);
		}
		
		OnScreenSizeChanged();
		
		//初始化窗口信息
		openCount++;
		if(openCount == 1)
		{
			firstOpen = true;
			
			if(!isInited)
			{
				Init();
				isInited = true;
			}
		}
		else
		{
			firstOpen = false;
		}
		
		//刷新窗口
		Refresh();
	}
	
	/// <summary>
	/// 关闭窗口
	/// </param>
	public virtual void Close(bool byuser)
	{
		if(!Visible)
			return;
		
		//先关闭当前窗口, 再打开其他窗口
		SetVisible(false);
		
		//恢复其他窗口
		delayopenwin();
	}
	
	void delayopenwin()
	{
		if(fullScreenWindow)
		{
			foreach(Window window in UIManager.openedWindowListWhenOpen)
			{
				window.Open(true);
			}
		}
	}
	
	protected void SetVisible(bool visible)
	{
		if(this.Visible != visible)
		{
			if(!visible && this.Visible)
				RefreshDefaultHideChildren();
			
			offset.gameObject.SetActiveRecursively(visible);
			if(visible)
			{
				HideDefaultHideChildren();
				anchor.ForceUpdate();
			}
		}
		
//		Logic.GetInstance().updateCursor();
		
		//二级窗口才添加到管理列表
		if(!firstWindow)
		{
			if(visible)
			{
				UIManager.currentFocusWindow = this;
				if(!UIManager.openedSecondWindowList.Contains(this))
					UIManager.openedSecondWindowList.Add(this);
			}
			else
			{
				if(UIManager.currentFocusWindow = this)
					UIManager.currentFocusWindow = null;
				
				if(UIManager.openedSecondWindowList.Contains(this))
					UIManager.openedSecondWindowList.Remove(this);
			}
		}
	}
	
	public virtual void Refresh()
	{
		
	}
	
	/// <summary>
	/// 清除窗口数据
	/// </summary>
	public virtual void Clean()
	{
		openCount = 0;
		firstOpen = false;
	}
	
	/// <summary>
	/// 设置窗口图层
	/// depth : 图层
	/// </param>
	public void SetDepth(float depth)
	{
		UIManager.SetControlPositionZ(offset.gameObject, depth);
		
		//同时提升窗口下的子空间锚点
		
		foreach(ChildAnchorInfo childAnchorInfo in childAnchorInfoList)
		{
			if(childAnchorInfo.offset != null)
				UIManager.SetControlPositionZ(childAnchorInfo.offset.gameObject, depth + childAnchorInfo.deletaDepth);
			
			childAnchorInfo.anchor.ForceUpdate();
		}
	}
	
	void LoadAttributes()
	{
		string dbPath = Directory.GetParent(UnityEngine.Application.dataPath).FullName + "/data/GameResources/UI/Configs" + gameObject.name + ".xml";
		if(File.Exists(dbPath))
		{
			WindowDB db = XML<WindowDB>.LoadFromPath(dbPath);
			db.UpdateNodes(transform);
		}
	}
	
	#region //DefaultHide
	
	public void RefreshDefaultHideChildren()
	{
		if(Visible)
		{
			hideChildren.Clear();
			
			for(int i = 0; i < transform.childCount; i++)
				CheckDisableChildren(transform.GetChild(i));
		}
	}
	
	void CheckDisableChildren(Transform obj)
	{
		if(!obj.gameObject.activeInHierarchy)
		{
			hideChildren.Add(obj);
		}
		
		for(int i = 0; i < obj.childCount; i++)
		{
			CheckDisableChildren(obj.GetChild(i));
		}
	}
	
	public void HideDefaultHideChildren()
	{
		foreach(Transform obj in hideChildren)
		{
			if(obj != null)
				obj.gameObject.SetActive(false);
		}
	}
	
	/// <summary>
	/// S设置窗口下控件的默认显隐属性
	/// </summary>
	public void SetChildDefaultHide(Transform obj, bool hide, bool toChildren)
	{
		if(obj == null)
			return;
		
		if(NGUITools.FindInParents<Window>(obj.gameObject) != this)
			return;
		
		if(hideChildren.Contains(obj))
		{
			if(hide)
				return;
			else
				hideChildren.Remove(obj);
		}
		else if(hide)
		{
			hideChildren.Add(obj);
		}
		
		if(toChildren)
		{
			for(int i = 0; i < obj.childCount; i++)
			{
				SetChildDefaultHide(obj.GetChild(i), hide, toChildren);
			}
		}
	}
	
	#endregion //DefaultHide
	
	/// <summary>
	/// 窗口聚焦
	/// </summary>
	public virtual void OnFocus()
	{
		if(firstWindow)
		{
			UIManager.openedSecondWindowList.Remove(this);
			UIManager.openedSecondWindowList.Add(this);
			UIManager.UpdateSecondWindowDepth();
		}
	}
	
	/// <summary>
	/// 窗口失焦
	/// </summary>
	public virtual void OnLostFocus()
	{
		
	}
	
	#region //Anchor Lock
	
	/// <summary>
	/// 窗口整体拖动时, 解除内部屏幕锚点
	/// </summary>
	[UnityEngine.ContextMenu("UnLockAnchor")]
	public void UnLoackAnchor()
	{
		foreach(ChildAnchorInfo childAnchorInfo in childAnchorInfoList)
		{
			if(childAnchorInfo.anchor != null)
				childAnchorInfo.anchor.enabled = false;
		}
	}
	
	/// <summary>
	/// 窗口停止拖动时, 锁定内部屏幕锚点
	/// </summary>
	[UnityEngine.ContextMenu("LockAnchor")]
	public void LoackAnchor()
	{
		foreach(ChildAnchorInfo childAnchorInfo in childAnchorInfoList)
		{
			if(childAnchorInfo.anchor != null)
				childAnchorInfo.anchor.enabled = true;
		}
	}
	
	#endregion //Anchor Lock
	
	/// <summary>
	/// 分辨率设置
	/// </summary>
	public virtual void OnScreenSizeChanged()
	{
		List<UIDragWindow> dragWindowList = new List<UIDragWindow>();
		foreach(UIDragWindow dragWindow in dragWindowList)
		{
			dragWindow.UpdateDragPanel();
		}
		
		anchor.ForceUpdate();
		foreach(ChildAnchorInfo anchorInfo in childAnchorInfoList)
		{
			if(anchorInfo.anchor != null)
				anchorInfo.anchor.ForceUpdate();
		}
	}
	
	/// <summary>
	/// 场景跳转前 逻辑
	/// </summary>
	public virtual void OnReadyToLoadScene()
	{
		
	}
}
